import { templateDef, templateFile } from "@/api";
import { HeightUtil } from "@/util";
import { createAtom, useStore } from "@/util/hooks";
import { Store } from "@/util/hooks/use-store";
import { Tree } from "@arco-design/web-react";
import { useHover } from "ahooks";
import { useEffect, useRef } from "react";
import { TemplateFileTreeAdapter, TemplateFileUtil } from ".";
import { TemplateDefEditorAtom, TemplateFileFormAtom } from "..";
import { TemplateTreeHeader } from "./header";
import { TemplateFileTreeStore } from "./inteface";
import { TemplateFileContextMenu } from "./menu";
import { TemplateFileModal } from "./modal-file";
import "./style.less";
import { TemplateRenameModal } from "./rename-file";

export const TemplateTreeAtom = createAtom<TemplateFileTreeStore>({
  originData: [],
  data: [],
  isFileSelected: false,
});

async function init(store: Store<TemplateFileTreeStore>) {
  const res = await templateFile.list();
  const treeData = TemplateFileTreeAdapter.toTreeData(res.data);
  store.updateStore({
    data: treeData,
    selectedKey: undefined,
    originData: res.data || [],
    checkedKeys: [],
  });
}

export const TemplateFileTree = () => {
  const treeRef = useRef(null);
  const store = useStore(TemplateTreeAtom);
  const formStore = useStore(TemplateFileFormAtom);
  const editorStore = useStore(TemplateDefEditorAtom);
  const isHovering = useHover(treeRef);
  const rightButtonClickRef = useRef<boolean>(false);

  const { isFileSelected, selectedKey } = store.value;

  async function initEditor() {
    const res = await templateDef.getById(store.value.selectedKey!);
    if (res.success) {
      formStore.updateStore({
        data: res.data,
        requestFormUpdate: true,
      });
      editorStore.updateStore({
        data: res.data.data || "",
      });
    }
  }

  useEffect(() => {
    init(store);
  }, []);

  useEffect(() => {
    if (isHovering) {
      const node = treeRef.current as any;
      node.force();
    }
  }, [isHovering]);

  useEffect(() => {
    if (isFileSelected) {
      initEditor();
    }
  }, [isFileSelected, selectedKey]);

  return (
    <>
      <TemplateTreeHeader />
      <TemplateFileContextMenu>
        <Tree
          ref={treeRef}
          style={{ height: HeightUtil.fillHeightStyle(2) }}
          checkable
          blockNode
          treeData={store.value.data}
          checkedStrategy="child"
          defaultExpandedKeys={[]}
          className="template-tree content"
          selectedKeys={
            store.value.selectedKey ? [store.value.selectedKey] : undefined
          }
          checkedKeys={store.value.checkedKeys}
          onMouseDown={(e) => {
            // 右键点击时，触发点击事件（使用点击事件来确定哪条数据被点击了）
            // see onSelect
            if (e.button === 2) {
              store.updateStore({
                clickedKey: undefined,
              });
              rightButtonClickRef.current = true;
              e.target.click();
              return;
            }
            const target = e.target;
            if (
              store.value.selectedKey &&
              String(target.className).includes("template-tree")
            ) {
              store.updateStore({
                selectedKey: undefined,
              });
            }
          }}
          onCheck={(checkedKeys) => store.updateStore({ checkedKeys })}
          onSelect={(selectedKeys) => {
            const selectedKey = selectedKeys[0];
            const originData = store.value.originData;
            const record = TemplateFileUtil.getFileRecord(
              selectedKey,
              originData
            );

            // 若是右键触发的选择事件，不进行选择，而使用clickedKey来缓存当前选择项
            // 其他组件会根据clickedKey来进行处理
            if (rightButtonClickRef.current) {
              store.updateStore({
                clickedKey: selectedKey,
              });
              rightButtonClickRef.current = false;
              return;
            }

            store.updateStoreAll((prev) => {
              const selected =
                !!prev.selectedKey && prev.selectedKey === selectedKey;
              return {
                ...prev,
                selectedKey: selected ? undefined : selectedKey,
                isFileSelected: selected || record?.directory ? false : true,
                clickedKey: selected ? undefined : selectedKey,
              };
            });
          }}
        />
        <div></div>
      </TemplateFileContextMenu>
      <TemplateFileModal />
      <TemplateRenameModal />
    </>
  );
};

TemplateFileTree.init = init;
